#include "mpHttpRequestMessageImpl.h"
#include "mpDateUtils.h"
#include "mpHttpParams.h"
#include "mpHttpException.h"

namespace MP{
namespace HTTP{
namespace INTERNAL{

HttpRequestMessageImpl::HttpRequestMessageImpl(const std::string & uri,
                                               MP::HTTP::HTTP_METHOD httpMethod)
    : _url(uri),_httpHeaders(),_sslSettings()
{
    setHttpMethod(httpMethod);
}

HttpRequestMessageImpl::HttpRequestMessageImpl(const Url& uri,
                                               MP::HTTP::HTTP_METHOD httpMethod)
    :_url(uri),_httpHeaders(),_sslSettings()
{
    setHttpMethod(httpMethod);
}

HttpRequestMessageImpl::HttpRequestMessageImpl(const Url& baseAddress,
                                               const std::string & relativeUri,
                                               MP::HTTP::HTTP_METHOD httpMethod)
    :_url(baseAddress,relativeUri),_httpHeaders(),_sslSettings()
{
    setHttpMethod(httpMethod);
}



const std::string& HttpRequestMessageImpl::getHttpMethod() const {
    return _httpMethod;
}

void HttpRequestMessageImpl::setHttpMethod(MP::HTTP::HTTP_METHOD httpMethod){
    _httpMethod = MP::StringUtils::httpMethodToString(httpMethod);
}

/***************************************************
 * 关于 URL
 ***************************************************/

const std::string& HttpRequestMessageImpl::getScheme() const{
    return _url.getScheme();
}

const std::string& HttpRequestMessageImpl::getHost() const{
    return _url.getHost();
}

unsigned short HttpRequestMessageImpl::getPort() const{
    return _url.getPort();
}

const std::string& HttpRequestMessageImpl::getRelativeUri() const{
    return _url.getRelativeUri();
}

/***************************************************
 * 关于 HttpRequestHeaders
 ***************************************************/

HttpRequestHeaders& HttpRequestMessageImpl::getHttpRequestHeaders(){
    return _httpHeaders;
}

/***************************************************
 * 关于 SslSettings
 ***************************************************/

SslSettings& HttpRequestMessageImpl::getSslSettings() {
    return _sslSettings;
}

/***************************************************
 * 关于 HttpRequestContent
 ***************************************************/
void HttpRequestMessageImpl::setHttpRequestContent(HttpRequestContent::ptr_s requestContent){

    if(!requestContent){
        return;
    }
    _requestContent = requestContent;

    //    //判断requestContent是否为Form提交，如果是则需要设置 Content-Type
    //    std::shared_ptr<HttpRequestMultipartContent> requestContentMultipart;
    //    requestContentMultipart = std::dynamic_pointer_cast<HttpRequestMultipartContent>(_requestContent);
}

HttpRequestContent::ptr_s HttpRequestMessageImpl::getHttpRequestContent() const {
    if(!_requestContent){
        throw HttpException("Invalid HttpRequestContent , unset value");
    }
    return _requestContent;
}


/***************************************************
 * 生成请求头部Buffer
 * POST /jobs HTTP/1.1
 * Host: <UIN>.cos-control.<Region>.myqcloud.com
 * Date: GMT Date
 * Content-Type: application/xml
 * Content-Length: Content Length
 * Authorization: Auth String
 * x-cos-appid: <APPID>
 ***************************************************/

void HttpRequestMessageImpl::getRequestHeaderBuffers(std::string& buf){
    buf.clear();

    //POST /jobs HTTP/1.1
    buf.append(_httpMethod + " " + _url.getRelativeUri() + " HTTP/1.1" + MP::HTTP::CRLF);
    //Host: <UIN>.cos-control.<Region>.myqcloud.com
    buf.append("Host: ")
            .append(_url.getHost())
            .append(":")
            .append(std::to_string(_url.getPort()))
            .append(MP::HTTP::CRLF);

    //Date: GMT Date
    buf.append(MP::HTTP::HK_DATE)
            .append(MP::HTTP::HEADER_SEPARATOR)
            .append(MP::DateUtils::get_now_gmt_string())
            .append(MP::HTTP::CRLF);

    if(_requestContent){
        //Content-Type
        if(!_requestContent->getContentType().empty()){
            buf.append(MP::HTTP::HK_CONTENT_TYPE)
                    .append(MP::HTTP::HEADER_SEPARATOR)
                    .append(_requestContent->getContentType())
                    .append(MP::HTTP::CRLF);
        }

        //Content-Length
        if(_requestContent->getContentLength() > 0){
            buf.append(MP::HTTP::HK_CONTENT_LENGTH)
                    .append(MP::HTTP::HEADER_SEPARATOR)
                    .append(std::to_string(_requestContent->getContentLength()))
                    .append(MP::HTTP::CRLF);
        }
    }

    //User-Agent
    buf.append(MP::HTTP::HK_USERAGENT)
            .append(MP::HTTP::HEADER_SEPARATOR)
            .append(_httpHeaders.getUserAgent())
            .append(".")
            .append(APP_VERSION)
            .append(MP::HTTP::CRLF);

    //Accept
    if(!_httpHeaders.getAccept().empty()){
        buf.append(MP::HTTP::HK_ACCEPT)
                .append(MP::HTTP::HEADER_SEPARATOR)
                .append(_httpHeaders.getAccept())
                .append(MP::HTTP::CRLF);
    }

    //AcceptEncoding
    if(!_httpHeaders.getAcceptEncoding().empty()){
        buf.append(MP::HTTP::HK_ACCEPT_ENCODING)
                .append(MP::HTTP::HEADER_SEPARATOR)
                .append(_httpHeaders.getAcceptEncoding())
                .append(MP::HTTP::CRLF);
    }

    //Cache-Control
    if(!_httpHeaders.getCache_Control().empty()){
        buf.append(MP::HTTP::HK_CACHE_CONTROL)
                .append(MP::HTTP::HEADER_SEPARATOR)
                .append(_httpHeaders.getCache_Control())
                .append(MP::HTTP::CRLF);
    }
    if(!_httpHeaders.getPragma().empty()){
        buf.append(MP::HTTP::HK_PRAGMA)
                .append(MP::HTTP::HEADER_SEPARATOR)
                .append(_httpHeaders.getPragma())
                .append(MP::HTTP::CRLF);
    }
    if(!_httpHeaders.getExpires().empty()){
        buf.append(MP::HTTP::HK_EXPIRES)
                .append(MP::HTTP::HEADER_SEPARATOR)
                .append(_httpHeaders.getExpires())
                .append(MP::HTTP::CRLF);
    }
    //Connection
    if(_httpHeaders.getConnectionKeepalive()){
        buf.append(MP::HTTP::HK_CONNECTION)
                .append(MP::HTTP::HEADER_SEPARATOR)
                .append(MP::HTTP::HK_CONNECTION_KEEP_ALIVE)
                .append(MP::HTTP::CRLF);
    }
    else{
        buf.append(MP::HTTP::HK_CONNECTION)
                .append(MP::HTTP::HEADER_SEPARATOR)
                .append(MP::HTTP::HK_CONNECTION_CLOSE)
                .append(MP::HTTP::CRLF);
    }

    //Authorization
    if(!_httpHeaders.getAuthorization().empty()){
        buf.append(MP::HTTP::HK_AUTHORIZATION)
                .append(MP::HTTP::HEADER_SEPARATOR)
                .append(_httpHeaders.getAuthorization())
                .append(MP::HTTP::CRLF);
    }

    //自定义的Header
    for (const HttpHeader& h : _httpHeaders.data()) {
        buf.append(h.key)
                .append(MP::HTTP::HEADER_SEPARATOR)
                .append(h.value)
                .append(MP::HTTP::CRLF);
    }

    buf.append(MP::HTTP::CRLF);


    //    std::ostringstream steam;
    //    steam << _httpMethod << " " << _url.getRelativeUri() << " HTTP/1.1" << MP::HTTP::CRLF;
    //    steam << "Host: " << _url.getHost() << ":" << _url.getPort() << MP::HTTP::CRLF;
    //    //Date
    //    steam << MP::HTTP::HK_DATE << MP::HTTP::HEADER_SEPARATOR << MP::DateUtils::getCurrentGtmDate() << MP::HTTP::CRLF;

    //    if(_requestContent){

    //        //Content-Type
    //        if(!_requestContent->getContentType().empty()){
    //            steam << MP::HTTP::HK_CONTENT_TYPE << MP::HTTP::HEADER_SEPARATOR << _requestContent->getContentType() << MP::HTTP::CRLF;
    //        }

    //        //Content-Length
    //        if(_requestContent->getContentLength() > 0){
    //            steam << MP::HTTP::HK_CONTENT_LENGTH << MP::HTTP::HEADER_SEPARATOR << std::to_string(_requestContent->getContentLength()) << MP::HTTP::CRLF;
    //        }
    //    }

    //    //User-Agent
    //    std::string agent;
    //    agent.append(_httpHeaders.getUserAgent());
    //    agent.append(".");
    //    agent.append(APP_VERSION);
    //    steam << MP::HTTP::HK_USERAGENT << MP::HTTP::HEADER_SEPARATOR << agent << MP::HTTP::CRLF;

    //    //Accept
    //    if(!_httpHeaders.getAccept().empty()){
    //        steam << MP::HTTP::HK_ACCEPT << MP::HTTP::HEADER_SEPARATOR << _httpHeaders.getAccept() << MP::HTTP::CRLF;
    //    }

    //    //Cache-Control
    //    if(!_httpHeaders.getCache_Control().empty()){
    //        steam << MP::HTTP::HK_CACHE_CONTROL << MP::HTTP::HEADER_SEPARATOR << _httpHeaders.getCache_Control() << MP::HTTP::CRLF;
    //    }
    //    if(!_httpHeaders.getPragma().empty()){
    //        steam << MP::HTTP::HK_PRAGMA << MP::HTTP::HEADER_SEPARATOR << _httpHeaders.getPragma() << MP::HTTP::CRLF;
    //    }
    //    if(!_httpHeaders.getExpires().empty()){
    //        steam << MP::HTTP::HK_EXPIRES << MP::HTTP::HEADER_SEPARATOR << _httpHeaders.getExpires() << MP::HTTP::CRLF;
    //    }

    //    //Connection
    //    if(_httpHeaders.getConnectionKeepalive()){
    //        steam << MP::HTTP::HK_CONNECTION << MP::HTTP::HEADER_SEPARATOR << MP::HTTP::HK_CONNECTION_KEEP_ALIVE << MP::HTTP::CRLF;
    //    }
    //    else{
    //        steam << MP::HTTP::HK_CONNECTION << MP::HTTP::HEADER_SEPARATOR << MP::HTTP::HK_CONNECTION_CLOSE << MP::HTTP::CRLF;
    //    }

    //    //Authorization
    //    if(!_httpHeaders.getAuthorization().empty()){
    //        steam << MP::HTTP::HK_AUTHORIZATION << MP::HTTP::HEADER_SEPARATOR << _httpHeaders.getAuthorization() << MP::HTTP::CRLF;
    //    }

    //    //自定义的Header
    //    for (const HttpHeader& h : _httpHeaders.data()) {
    //        steam << h.key << MP::HTTP::HEADER_SEPARATOR << h.value << MP::HTTP::CRLF;
    //    }

    //    steam << MP::HTTP::CRLF;

    //    std::string str_header = steam.str();
    //    buffers.push_back(boost::asio::buffer(str_header));
}



}   //INTERNAL
}   //HTTP
}   //MP
